package com.web.music.impl;

//import java.io.File;
//import java.io.BufferedInputStream;
//import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Map;

import org.apache.log4j.Logger;

import com.web.music.interfaces.HTTPClient;
import com.web.music.model.Album;
import com.web.music.model.Artist;
import com.web.music.model.Genre;
import com.web.music.model.Person;

/**
 * Loads XML files from remote URL, extracts information from XML and saves it into database.
 */
public class RemoteMusicProcessor extends BaseMusicProcessor {

	static Logger logger = Logger.getLogger(DomXmlParser.class.getName());
	
	String peopleUrl;	// people.xml remote location
	String catalogUrl;	// catalog.xml remote location
	
	private HTTPClient httpClient;	
	
	public void execute(){	
		super.execute();
		logger.info("[RemoteMusicProcessor] Starting to download people info from URL: " + peopleUrl);
		
		// TODO [done]
		// This method is not implemented yet and will throw exception.
		// Your task is to implement downloading from remote URL.
		InputStream peopleXml = getHttpClient().download(peopleUrl);
		
		logger.info("[RemoteMusicProcessor] XML file with people info downloaded, starting parsing");
		Map<String,Person> people = getXmlParser().extractPeopleInfo(peopleXml);	
		logger.info("[RemoteMusicProcessor] People info extracted. In total [" + people.size() + "] items processed.");
		logger.info("[RemoteMusicProcessor] Saving people to database");
		getPersistence().saveAll(new ArrayList<Person>(people.values()));
		logger.info("[RemoteMusicProcessor] People info successfully saved into database");
		
		// TODO [done]
		// Your task is to continue with catalog.xml file parsing.
		// All data should appear in database after application execution finishes.
		InputStream catalogXml = getHttpClient().download(catalogUrl);
		InputStream catalogXml_1 = getHttpClient().download(catalogUrl);
		InputStream catalogXml_2 = getHttpClient().download(catalogUrl);
		
		
		//AKRA: I had to make it quick 'n dirty - spent many hours to find, how to clone inputstream
		//or how to make DocumentBuilder not to reset InputStream given as parameter.
		
		logger.info("[RemoteMusicProcessor] XML file with catalog info downloaded, starting parsing");
		logger.info("[RemoteMusicProcessor] Starting to extract genre info from file: " + catalogUrl);
		Map<String, Genre> genres = getXmlParser().extractGenreInfo(catalogXml);

		logger.info("[RemoteMusicProcessor] Genre info extracted. In total [" + genres.size() + "] items processed.");
		logger.info("[RemoteMusicProcessor] Saving genres to database");
		getPersistence().saveAll(new ArrayList<Genre>(genres.values()));
		logger.info("[RemoteMusicProcessor] Genre info successfully saved into database");
		
		logger.info("[RemoteMusicProcessor] Starting to extract Artist info from file: " + catalogUrl);
		Map<String, Artist> artists = getXmlParser().extractArtistInfo(catalogXml_1, genres, people);
		logger.info("[RemoteMusicProcessor] Artist info extracted. In total [" + artists.size() + "] items processed.");
		logger.info("[RemoteMusicProcessor] Saving artists to database");
		getPersistence().saveAll(new ArrayList<Artist>(artists.values()));
		logger.info("[RemoteMusicProcessor] Artist info successfully saved into database");

		logger.info("[RemoteMusicProcessor] Starting to extract Album info from file: " + catalogUrl);
		Map<String, Album> albums = getXmlParser().extractAlbumInfo(catalogXml_2, artists, genres);
		logger.info("[RemoteMusicProcessor] Album info extracted. In total [" + albums.size() + "] items processed.");
		
		logger.info("[RemoteMusicProcessor] Saving albums to database");
		getPersistence().saveAll(new ArrayList<Album>(albums.values()));
		logger.info("[RemoteMusicProcessor] Album info successfully saved into database");
	
	}

	public String getPeopleUrl() {
		return peopleUrl;
	}

	public void setPeopleUrl(String peopleUrl) {
		this.peopleUrl = peopleUrl;
	}

	public String getCatalogUrl() {
		return catalogUrl;
	}

	public void setCatalogUrl(String catalogUrl) {
		this.catalogUrl = catalogUrl;
	}
	
	public HTTPClient getHttpClient() {
		return httpClient;
	}
	public void setHttpClient(HTTPClient httpClient) {
		this.httpClient = httpClient;
	}
	
}
